

#ifdef a
#include<iostream>
using namespace std;

const double Pai = 3.14;

//抽象类（接口类）-》不可继承
class Shape {
public:
	//纯虚函数
	virtual double Getarea() = 0 {
		cout << "也可以有函数体" << endl;
	}
	virtual double Getperimeter() = 0;//周长
};
class Circle : public Shape
{
public:
	Circle(double r)
		:_r(r)
	{}

	//抽象类的子类只有将基类的纯叙述完全重写后才能进行实例化，否则依旧为抽象类
	double Getarea() override {
		return Pai * _r * _r;
	}
	double Getperimeter() override{
		return Pai * _r * 2;
	}

private:
	double _r;
};

class Rect : public Shape
{
public:
	Rect(double length, double width)
		:_length(length)
		,_width(width)
	{}
	double Getarea() override {
		return _length * _width;
	}
	double Getperimeter() override {
		return 2 * (_length + _width);
	}

private:
	double _length;
	double _width;
};

//直角三角形

class Triangle : public Shape
{
public:
	Triangle(double a, double b, double c)
		:_a(a)
		,_b(b)
		,_c(c)
	{}

	double Getarea() override {
		return 0.5 * _a * _b;
	}
	double Getperimeter()override {
		return _a + _b + _c;
	}

private:
	double _a;
	double _b;
	double _c;
};

//虽然抽象类不可实例化，但仍然是一种自定义类型
void TestShape(Shape& s) {
	cout << "Area:" << s.Getarea() << endl;
	cout << "Perimeter:" << s.Getperimeter() << endl;
}
int main() {
	//Shape s;->抽象类无法实例化
	Circle c(10);
	Triangle t(3, 4, 5);
	Rect r(5, 10);
	TestShape(c);
	TestShape(t);
	TestShape(r);

	return 0;
}
//纯虚函数（语法上也可以实现自己的语法体，即定义，但无意义，最后又不用）

//抽象类（接口类）：包含纯虚函数的类，本身就是不具体的，不能实例化对象,其子类必须对所有基类的纯虚函数进行重写，否则仍旧为抽象类


#endif